1use crate::ext::io::*;
3use crate::scripts::base::*;
4use crate::types::*;
5use crate::utils::pcm::*;
6use crate::utils::struct_pack::*;
7use anyhow::Result;
8use int_enum::IntEnum;
9use msg_tool_macro::*;
10use overf::wrapping;
11use std::io::{Read, Seek, Write};
12
13#[derive(Debug)]
14pub struct PcmBuilder {}
16
17impl PcmBuilder {
18 pub fn new() -> Self {
20 Self {}
21 }
22}
23
24impl ScriptBuilder for PcmBuilder {
25 fn default_encoding(&self) -> Encoding {
26 Encoding::Utf8
27 }
28
29 fn build_script(
30 &self,
31 buf: Vec<u8>,
32 _filename: &str,
33 _encoding: Encoding,
34 _archive_encoding: Encoding,
35 config: &ExtraConfig,
36 _archive: Option<&Box<dyn Script>>,
37 ) -> Result<Box<dyn Script>> {
38 Ok(Box::new(Pcm::new(MemReader::new(buf), config)?))
39 }
40
41 fn build_script_from_file(
42 &self,
43 filename: &str,
44 _encoding: Encoding,
45 _archive_encoding: Encoding,
46 config: &ExtraConfig,
47 _archive: Option<&Box<dyn Script>>,
48 ) -> Result<Box<dyn Script>> {
49 let file = std::fs::File::open(filename)?;
50 let f = std::io::BufReader::new(file);
51 Ok(Box::new(Pcm::new(f, config)?))
52 }
53
54 fn build_script_from_reader(
55 &self,
56 reader: Box<dyn ReadSeek>,
57 _filename: &str,
58 _encoding: Encoding,
59 _archive_encoding: Encoding,
60 config: &ExtraConfig,
61 _archive: Option<&Box<dyn Script>>,
62 ) -> Result<Box<dyn Script>> {
63 Ok(Box::new(Pcm::new(reader, config)?))
64 }
65
66 fn extensions(&self) -> &'static [&'static str] {
67 &["pcm"]
68 }
69
70 fn script_type(&self) -> &'static ScriptType {
71 &ScriptType::CircusPcm
72 }
73
74 fn is_this_format(&self, _filename: &str, buf: &[u8], buf_len: usize) -> Option<u8> {
75 if buf_len >= 4 && buf.starts_with(b"XPCM") {
76 Some(10)
77 } else {
78 None
79 }
80 }
81}
82
83#[derive(Debug, IntEnum)]
84#[repr(u32)]
85enum Mode {
86 Raw = 0,
87 Lzss = 1,
88 Adpcm = 2,
89 Zlib = 3,
90 Ogg = 5,
91}
92
93#[derive(Debug, StructPack, StructUnpack)]
94struct Header {
95 src_size: u32,
96 _mode: u32,
97 #[skip_pack_if(self.mode() != 5)]
98 #[skip_unpack_if((_mode & 0xFF) != 5)]
99 ogg_size: u32,
100 #[skip_pack_if(self.mode() == 5)]
101 #[skip_unpack_if((_mode & 0xFF) == 5)]
102 pcm: Option<PcmFormat>,
103}
104
105impl Header {
106 pub fn mode(&self) -> u32 {
107 self._mode & 0xFF
108 }
109
110 pub fn extra(&self) -> u32 {
111 (self._mode >> 8) & 0xFF
112 }
113}
114
115#[derive(Debug)]
116pub struct Pcm {
118 header: Header,
119 data: MemReader,
120}
121
122impl Pcm {
123 pub fn new<R: Read + Seek>(mut reader: R, _config: &ExtraConfig) -> Result<Self> {
128 let mut magic = [0u8; 4];
129 reader.read_exact(&mut magic)?;
130 if &magic != b"XPCM" {
131 return Err(anyhow::anyhow!("Invalid PCM header magic: {:?}", magic));
132 }
133 let header = Header::unpack(&mut reader, false, Encoding::Utf8)?;
134 let mode = Mode::try_from(header.mode())
135 .map_err(|_| anyhow::anyhow!("Unsupported PCM mode: {}", header.mode()))?;
136 let data = match mode {
137 Mode::Ogg => {
138 if header.ogg_size == 0 {
139 return Err(anyhow::anyhow!("Invalid OGG size in PCM header"));
140 }
141 let mut data = vec![0u8; header.ogg_size as usize];
142 reader.read_exact(&mut data)?;
143 data
144 }
145 Mode::Raw => {
146 let mut data = vec![0u8; header.src_size as usize];
147 reader.read_exact(&mut data)?;
148 data
149 }
150 Mode::Adpcm => Self::decode_adpcm(&mut reader, header.src_size as usize)?,
151 _ => {
152 PcmDecoder::new(reader, header.src_size as usize, header.extra(), mode)?.unpack()?
153 }
154 };
155 Ok(Self {
156 header,
157 data: MemReader::new(data),
158 })
159 }
160
161 fn decode_adpcm<R: Read + Seek>(mut input: R, pcm_size: usize) -> Result<Vec<u8>> {
162 let input_len = input.stream_length()? - input.stream_position()?;
163 let mut output = Vec::with_capacity(pcm_size);
164 let mut table = [0u32; 6];
165 let mut channel = 0;
166 let mut src = 0;
167 let mut dst = 0;
168 while src < input_len && dst < pcm_size as u32 {
169 let data = input.read_i8()?;
170 src += 1;
171 table[channel * 3] =
172 table[channel * 3].wrapping_add((data as u32) << (table[channel * 3 + 1] & 0xFF));
173 if data == 0 {
174 if table[channel * 3 + 1] != 0 {
175 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_sub(1);
176 }
177 } else if data == 0x7F || data == -0x80 {
178 if table[channel * 3 + 1] != 8 {
179 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_add(1);
180 }
181 }
182 output.push(table[channel * 3] as u8);
183 output.push((table[channel * 3] >> 8) as u8);
184 channel = 1 - channel;
185 dst += 2;
186 }
187 Ok(output)
188 }
189}
190
191impl Script for Pcm {
192 fn default_output_script_type(&self) -> OutputScriptType {
193 OutputScriptType::Custom
194 }
195
196 fn default_format_type(&self) -> FormatOptions {
197 FormatOptions::None
198 }
199
200 fn is_output_supported(&self, output: OutputScriptType) -> bool {
201 matches!(output, OutputScriptType::Custom)
202 }
203
204 fn custom_output_extension<'a>(&'a self) -> &'a str {
205 if self.header.mode() == 5 {
206 "ogg"
207 } else {
208 "wav"
209 }
210 }
211
212 fn custom_export(&self, filename: &std::path::Path, _encoding: Encoding) -> Result<()> {
213 let mut writer = std::fs::File::create(filename)?;
214 if self.header.mode() == 5 {
215 writer.write_all(&self.data.data)?;
216 } else {
217 let fmt = self
218 .header
219 .pcm
220 .as_ref()
221 .ok_or_else(|| anyhow::anyhow!("PCM format not found in header"))?;
222 write_pcm(fmt, self.data.to_ref(), writer)?;
223 }
224 Ok(())
225 }
226}
227
228const UNK_43A254: [u8; 320] = [
229 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
230 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
231 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
232 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
233 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
234 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
235 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
236 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
237 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
238 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
239 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
240 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
241 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
242 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
243 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
244 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
245 0x55, 0x05, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00,
246 0xAA, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
247 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
248 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
249];
250const DWORD_43A358: [i32; 2048] = [
251 0x1000, 0x0000, 0x0FFF, 0x0006, 0x0FFF, 0x000C, 0x0FFF, 0x0012, 0x0FFF, 0x0019, 0x0FFF, 0x001F,
252 0x0FFF, 0x0025, 0x0FFF, 0x002B, 0x0FFF, 0x0032, 0x0FFF, 0x0038, 0x0FFF, 0x003E, 0x0FFF, 0x0045,
253 0x0FFF, 0x004B, 0x0FFF, 0x0051, 0x0FFF, 0x0057, 0x0FFE, 0x005E, 0x0FFE, 0x0064, 0x0FFE, 0x006A,
254 0x0FFE, 0x0071, 0x0FFE, 0x0077, 0x0FFE, 0x007D, 0x0FFD, 0x0083, 0x0FFD, 0x008A, 0x0FFD, 0x0090,
255 0x0FFD, 0x0096, 0x0FFC, 0x009D, 0x0FFC, 0x00A3, 0x0FFC, 0x00A9, 0x0FFC, 0x00AF, 0x0FFB, 0x00B6,
256 0x0FFB, 0x00BC, 0x0FFB, 0x00C2, 0x0FFB, 0x00C8, 0x0FFA, 0x00CF, 0x0FFA, 0x00D5, 0x0FFA, 0x00DB,
257 0x0FF9, 0x00E2, 0x0FF9, 0x00E8, 0x0FF9, 0x00EE, 0x0FF8, 0x00F4, 0x0FF8, 0x00FB, 0x0FF7, 0x0101,
258 0x0FF7, 0x0107, 0x0FF7, 0x010D, 0x0FF6, 0x0114, 0x0FF6, 0x011A, 0x0FF5, 0x0120, 0x0FF5, 0x0127,
259 0x0FF4, 0x012D, 0x0FF4, 0x0133, 0x0FF3, 0x0139, 0x0FF3, 0x0140, 0x0FF2, 0x0146, 0x0FF2, 0x014C,
260 0x0FF1, 0x0152, 0x0FF1, 0x0159, 0x0FF0, 0x015F, 0x0FF0, 0x0165, 0x0FEF, 0x016B, 0x0FEF, 0x0172,
261 0x0FEE, 0x0178, 0x0FEE, 0x017E, 0x0FED, 0x0184, 0x0FEC, 0x018B, 0x0FEC, 0x0191, 0x0FEB, 0x0197,
262 0x0FEB, 0x019D, 0x0FEA, 0x01A4, 0x0FE9, 0x01AA, 0x0FE9, 0x01B0, 0x0FE8, 0x01B6, 0x0FE7, 0x01BD,
263 0x0FE7, 0x01C3, 0x0FE6, 0x01C9, 0x0FE5, 0x01CF, 0x0FE4, 0x01D6, 0x0FE4, 0x01DC, 0x0FE3, 0x01E2,
264 0x0FE2, 0x01E8, 0x0FE1, 0x01EF, 0x0FE1, 0x01F5, 0x0FE0, 0x01FB, 0x0FDF, 0x0201, 0x0FDE, 0x0208,
265 0x0FDE, 0x020E, 0x0FDD, 0x0214, 0x0FDC, 0x021A, 0x0FDB, 0x0221, 0x0FDA, 0x0227, 0x0FD9, 0x022D,
266 0x0FD9, 0x0233, 0x0FD8, 0x0239, 0x0FD7, 0x0240, 0x0FD6, 0x0246, 0x0FD5, 0x024C, 0x0FD4, 0x0252,
267 0x0FD3, 0x0259, 0x0FD2, 0x025F, 0x0FD1, 0x0265, 0x0FD0, 0x026B, 0x0FCF, 0x0271, 0x0FCE, 0x0278,
268 0x0FCD, 0x027E, 0x0FCC, 0x0284, 0x0FCB, 0x028A, 0x0FCA, 0x0290, 0x0FC9, 0x0297, 0x0FC8, 0x029D,
269 0x0FC7, 0x02A3, 0x0FC6, 0x02A9, 0x0FC5, 0x02AF, 0x0FC4, 0x02B6, 0x0FC3, 0x02BC, 0x0FC2, 0x02C2,
270 0x0FC1, 0x02C8, 0x0FC0, 0x02CE, 0x0FBF, 0x02D5, 0x0FBE, 0x02DB, 0x0FBD, 0x02E1, 0x0FBB, 0x02E7,
271 0x0FBA, 0x02ED, 0x0FB9, 0x02F3, 0x0FB8, 0x02FA, 0x0FB7, 0x0300, 0x0FB6, 0x0306, 0x0FB4, 0x030C,
272 0x0FB3, 0x0312, 0x0FB2, 0x0318, 0x0FB1, 0x031F, 0x0FB0, 0x0325, 0x0FAE, 0x032B, 0x0FAD, 0x0331,
273 0x0FAC, 0x0337, 0x0FAB, 0x033D, 0x0FA9, 0x0344, 0x0FA8, 0x034A, 0x0FA7, 0x0350, 0x0FA5, 0x0356,
274 0x0FA4, 0x035C, 0x0FA3, 0x0362, 0x0FA1, 0x0368, 0x0FA0, 0x036F, 0x0F9F, 0x0375, 0x0F9D, 0x037B,
275 0x0F9C, 0x0381, 0x0F9B, 0x0387, 0x0F99, 0x038D, 0x0F98, 0x0393, 0x0F96, 0x0399, 0x0F95, 0x03A0,
276 0x0F94, 0x03A6, 0x0F92, 0x03AC, 0x0F91, 0x03B2, 0x0F8F, 0x03B8, 0x0F8E, 0x03BE, 0x0F8C, 0x03C4,
277 0x0F8B, 0x03CA, 0x0F89, 0x03D0, 0x0F88, 0x03D7, 0x0F86, 0x03DD, 0x0F85, 0x03E3, 0x0F83, 0x03E9,
278 0x0F82, 0x03EF, 0x0F80, 0x03F5, 0x0F7F, 0x03FB, 0x0F7D, 0x0401, 0x0F7B, 0x0407, 0x0F7A, 0x040D,
279 0x0F78, 0x0413, 0x0F77, 0x041A, 0x0F75, 0x0420, 0x0F73, 0x0426, 0x0F72, 0x042C, 0x0F70, 0x0432,
280 0x0F6E, 0x0438, 0x0F6D, 0x043E, 0x0F6B, 0x0444, 0x0F69, 0x044A, 0x0F68, 0x0450, 0x0F66, 0x0456,
281 0x0F64, 0x045C, 0x0F63, 0x0462, 0x0F61, 0x0468, 0x0F5F, 0x046E, 0x0F5D, 0x0474, 0x0F5C, 0x047A,
282 0x0F5A, 0x0480, 0x0F58, 0x0486, 0x0F56, 0x048C, 0x0F55, 0x0492, 0x0F53, 0x0498, 0x0F51, 0x049E,
283 0x0F4F, 0x04A5, 0x0F4D, 0x04AB, 0x0F4B, 0x04B1, 0x0F4A, 0x04B7, 0x0F48, 0x04BD, 0x0F46, 0x04C3,
284 0x0F44, 0x04C9, 0x0F42, 0x04CF, 0x0F40, 0x04D5, 0x0F3E, 0x04DB, 0x0F3C, 0x04E0, 0x0F3B, 0x04E6,
285 0x0F39, 0x04EC, 0x0F37, 0x04F2, 0x0F35, 0x04F8, 0x0F33, 0x04FE, 0x0F31, 0x0504, 0x0F2F, 0x050A,
286 0x0F2D, 0x0510, 0x0F2B, 0x0516, 0x0F29, 0x051C, 0x0F27, 0x0522, 0x0F25, 0x0528, 0x0F23, 0x052E,
287 0x0F21, 0x0534, 0x0F1F, 0x053A, 0x0F1D, 0x0540, 0x0F1B, 0x0546, 0x0F18, 0x054C, 0x0F16, 0x0552,
288 0x0F14, 0x0558, 0x0F12, 0x055D, 0x0F10, 0x0563, 0x0F0E, 0x0569, 0x0F0C, 0x056F, 0x0F0A, 0x0575,
289 0x0F08, 0x057B, 0x0F05, 0x0581, 0x0F03, 0x0587, 0x0F01, 0x058D, 0x0EFF, 0x0593, 0x0EFD, 0x0599,
290 0x0EFA, 0x059E, 0x0EF8, 0x05A4, 0x0EF6, 0x05AA, 0x0EF4, 0x05B0, 0x0EF2, 0x05B6, 0x0EEF, 0x05BC,
291 0x0EED, 0x05C2, 0x0EEB, 0x05C7, 0x0EE8, 0x05CD, 0x0EE6, 0x05D3, 0x0EE4, 0x05D9, 0x0EE2, 0x05DF,
292 0x0EDF, 0x05E5, 0x0EDD, 0x05EB, 0x0EDB, 0x05F0, 0x0ED8, 0x05F6, 0x0ED6, 0x05FC, 0x0ED4, 0x0602,
293 0x0ED1, 0x0608, 0x0ECF, 0x060E, 0x0ECD, 0x0613, 0x0ECA, 0x0619, 0x0EC8, 0x061F, 0x0EC5, 0x0625,
294 0x0EC3, 0x062B, 0x0EC0, 0x0630, 0x0EBE, 0x0636, 0x0EBC, 0x063C, 0x0EB9, 0x0642, 0x0EB7, 0x0648,
295 0x0EB4, 0x064D, 0x0EB2, 0x0653, 0x0EAF, 0x0659, 0x0EAD, 0x065F, 0x0EAA, 0x0664, 0x0EA8, 0x066A,
296 0x0EA5, 0x0670, 0x0EA3, 0x0676, 0x0EA0, 0x067B, 0x0E9E, 0x0681, 0x0E9B, 0x0687, 0x0E98, 0x068D,
297 0x0E96, 0x0692, 0x0E93, 0x0698, 0x0E91, 0x069E, 0x0E8E, 0x06A3, 0x0E8B, 0x06A9, 0x0E89, 0x06AF,
298 0x0E86, 0x06B5, 0x0E84, 0x06BA, 0x0E81, 0x06C0, 0x0E7E, 0x06C6, 0x0E7C, 0x06CB, 0x0E79, 0x06D1,
299 0x0E76, 0x06D7, 0x0E74, 0x06DC, 0x0E71, 0x06E2, 0x0E6E, 0x06E8, 0x0E6B, 0x06ED, 0x0E69, 0x06F3,
300 0x0E66, 0x06F9, 0x0E63, 0x06FE, 0x0E60, 0x0704, 0x0E5E, 0x070A, 0x0E5B, 0x070F, 0x0E58, 0x0715,
301 0x0E55, 0x071B, 0x0E53, 0x0720, 0x0E50, 0x0726, 0x0E4D, 0x072B, 0x0E4A, 0x0731, 0x0E47, 0x0737,
302 0x0E44, 0x073C, 0x0E42, 0x0742, 0x0E3F, 0x0748, 0x0E3C, 0x074D, 0x0E39, 0x0753, 0x0E36, 0x0758,
303 0x0E33, 0x075E, 0x0E30, 0x0763, 0x0E2D, 0x0769, 0x0E2B, 0x076F, 0x0E28, 0x0774, 0x0E25, 0x077A,
304 0x0E22, 0x077F, 0x0E1F, 0x0785, 0x0E1C, 0x078A, 0x0E19, 0x0790, 0x0E16, 0x0795, 0x0E13, 0x079B,
305 0x0E10, 0x07A0, 0x0E0D, 0x07A6, 0x0E0A, 0x07AC, 0x0E07, 0x07B1, 0x0E04, 0x07B7, 0x0E01, 0x07BC,
306 0x0DFE, 0x07C2, 0x0DFB, 0x07C7, 0x0DF8, 0x07CD, 0x0DF5, 0x07D2, 0x0DF2, 0x07D7, 0x0DEE, 0x07DD,
307 0x0DEB, 0x07E2, 0x0DE8, 0x07E8, 0x0DE5, 0x07ED, 0x0DE2, 0x07F3, 0x0DDF, 0x07F8, 0x0DDC, 0x07FE,
308 0x0DD9, 0x0803, 0x0DD5, 0x0809, 0x0DD2, 0x080E, 0x0DCF, 0x0813, 0x0DCC, 0x0819, 0x0DC9, 0x081E,
309 0x0DC6, 0x0824, 0x0DC2, 0x0829, 0x0DBF, 0x082E, 0x0DBC, 0x0834, 0x0DB9, 0x0839, 0x0DB6, 0x083F,
310 0x0DB2, 0x0844, 0x0DAF, 0x0849, 0x0DAC, 0x084F, 0x0DA9, 0x0854, 0x0DA5, 0x085A, 0x0DA2, 0x085F,
311 0x0D9F, 0x0864, 0x0D9B, 0x086A, 0x0D98, 0x086F, 0x0D95, 0x0874, 0x0D91, 0x087A, 0x0D8E, 0x087F,
312 0x0D8B, 0x0884, 0x0D87, 0x088A, 0x0D84, 0x088F, 0x0D81, 0x0894, 0x0D7D, 0x0899, 0x0D7A, 0x089F,
313 0x0D77, 0x08A4, 0x0D73, 0x08A9, 0x0D70, 0x08AF, 0x0D6C, 0x08B4, 0x0D69, 0x08B9, 0x0D65, 0x08BE,
314 0x0D62, 0x08C4, 0x0D5F, 0x08C9, 0x0D5B, 0x08CE, 0x0D58, 0x08D3, 0x0D54, 0x08D9, 0x0D51, 0x08DE,
315 0x0D4D, 0x08E3, 0x0D4A, 0x08E8, 0x0D46, 0x08EE, 0x0D43, 0x08F3, 0x0D3F, 0x08F8, 0x0D3C, 0x08FD,
316 0x0D38, 0x0902, 0x0D35, 0x0908, 0x0D31, 0x090D, 0x0D2D, 0x0912, 0x0D2A, 0x0917, 0x0D26, 0x091C,
317 0x0D23, 0x0921, 0x0D1F, 0x0927, 0x0D1C, 0x092C, 0x0D18, 0x0931, 0x0D14, 0x0936, 0x0D11, 0x093B,
318 0x0D0D, 0x0940, 0x0D09, 0x0945, 0x0D06, 0x094B, 0x0D02, 0x0950, 0x0CFE, 0x0955, 0x0CFB, 0x095A,
319 0x0CF7, 0x095F, 0x0CF3, 0x0964, 0x0CF0, 0x0969, 0x0CEC, 0x096E, 0x0CE8, 0x0973, 0x0CE5, 0x0978,
320 0x0CE1, 0x097D, 0x0CDD, 0x0982, 0x0CD9, 0x0987, 0x0CD6, 0x098D, 0x0CD2, 0x0992, 0x0CCE, 0x0997,
321 0x0CCA, 0x099C, 0x0CC7, 0x09A1, 0x0CC3, 0x09A6, 0x0CBF, 0x09AB, 0x0CBB, 0x09B0, 0x0CB7, 0x09B5,
322 0x0CB4, 0x09BA, 0x0CB0, 0x09BF, 0x0CAC, 0x09C4, 0x0CA8, 0x09C9, 0x0CA4, 0x09CE, 0x0CA0, 0x09D3,
323 0x0C9D, 0x09D7, 0x0C99, 0x09DC, 0x0C95, 0x09E1, 0x0C91, 0x09E6, 0x0C8D, 0x09EB, 0x0C89, 0x09F0,
324 0x0C85, 0x09F5, 0x0C81, 0x09FA, 0x0C7D, 0x09FF, 0x0C79, 0x0A04, 0x0C76, 0x0A09, 0x0C72, 0x0A0E,
325 0x0C6E, 0x0A12, 0x0C6A, 0x0A17, 0x0C66, 0x0A1C, 0x0C62, 0x0A21, 0x0C5E, 0x0A26, 0x0C5A, 0x0A2B,
326 0x0C56, 0x0A30, 0x0C52, 0x0A35, 0x0C4E, 0x0A39, 0x0C4A, 0x0A3E, 0x0C46, 0x0A43, 0x0C42, 0x0A48,
327 0x0C3E, 0x0A4D, 0x0C3A, 0x0A51, 0x0C36, 0x0A56, 0x0C31, 0x0A5B, 0x0C2D, 0x0A60, 0x0C29, 0x0A65,
328 0x0C25, 0x0A69, 0x0C21, 0x0A6E, 0x0C1D, 0x0A73, 0x0C19, 0x0A78, 0x0C15, 0x0A7C, 0x0C11, 0x0A81,
329 0x0C0D, 0x0A86, 0x0C08, 0x0A8B, 0x0C04, 0x0A8F, 0x0C00, 0x0A94, 0x0BFC, 0x0A99, 0x0BF8, 0x0A9D,
330 0x0BF4, 0x0AA2, 0x0BEF, 0x0AA7, 0x0BEB, 0x0AAC, 0x0BE7, 0x0AB0, 0x0BE3, 0x0AB5, 0x0BDF, 0x0ABA,
331 0x0BDA, 0x0ABE, 0x0BD6, 0x0AC3, 0x0BD2, 0x0AC8, 0x0BCE, 0x0ACC, 0x0BCA, 0x0AD1, 0x0BC5, 0x0AD5,
332 0x0BC1, 0x0ADA, 0x0BBD, 0x0ADF, 0x0BB8, 0x0AE3, 0x0BB4, 0x0AE8, 0x0BB0, 0x0AEC, 0x0BAC, 0x0AF1,
333 0x0BA7, 0x0AF6, 0x0BA3, 0x0AFA, 0x0B9F, 0x0AFF, 0x0B9A, 0x0B03, 0x0B96, 0x0B08, 0x0B92, 0x0B0C,
334 0x0B8D, 0x0B11, 0x0B89, 0x0B15, 0x0B85, 0x0B1A, 0x0B80, 0x0B1F, 0x0B7C, 0x0B23, 0x0B78, 0x0B28,
335 0x0B73, 0x0B2C, 0x0B6F, 0x0B31, 0x0B6A, 0x0B35, 0x0B66, 0x0B3A, 0x0B62, 0x0B3E, 0x0B5D, 0x0B42,
336 0x0B59, 0x0B47, 0x0B54, 0x0B4B, 0x0B50, 0x0B50, 0x0B4B, 0x0B54, 0x0B47, 0x0B59, 0x0B42, 0x0B5D,
337 0x0B3E, 0x0B62, 0x0B3A, 0x0B66, 0x0B35, 0x0B6A, 0x0B31, 0x0B6F, 0x0B2C, 0x0B73, 0x0B28, 0x0B78,
338 0x0B23, 0x0B7C, 0x0B1F, 0x0B80, 0x0B1A, 0x0B85, 0x0B15, 0x0B89, 0x0B11, 0x0B8D, 0x0B0C, 0x0B92,
339 0x0B08, 0x0B96, 0x0B03, 0x0B9A, 0x0AFF, 0x0B9F, 0x0AFA, 0x0BA3, 0x0AF6, 0x0BA7, 0x0AF1, 0x0BAC,
340 0x0AEC, 0x0BB0, 0x0AE8, 0x0BB4, 0x0AE3, 0x0BB8, 0x0ADF, 0x0BBD, 0x0ADA, 0x0BC1, 0x0AD5, 0x0BC5,
341 0x0AD1, 0x0BCA, 0x0ACC, 0x0BCE, 0x0AC8, 0x0BD2, 0x0AC3, 0x0BD6, 0x0ABE, 0x0BDA, 0x0ABA, 0x0BDF,
342 0x0AB5, 0x0BE3, 0x0AB0, 0x0BE7, 0x0AAC, 0x0BEB, 0x0AA7, 0x0BEF, 0x0AA2, 0x0BF4, 0x0A9D, 0x0BF8,
343 0x0A99, 0x0BFC, 0x0A94, 0x0C00, 0x0A8F, 0x0C04, 0x0A8B, 0x0C08, 0x0A86, 0x0C0D, 0x0A81, 0x0C11,
344 0x0A7C, 0x0C15, 0x0A78, 0x0C19, 0x0A73, 0x0C1D, 0x0A6E, 0x0C21, 0x0A69, 0x0C25, 0x0A65, 0x0C29,
345 0x0A60, 0x0C2D, 0x0A5B, 0x0C31, 0x0A56, 0x0C36, 0x0A51, 0x0C3A, 0x0A4D, 0x0C3E, 0x0A48, 0x0C42,
346 0x0A43, 0x0C46, 0x0A3E, 0x0C4A, 0x0A39, 0x0C4E, 0x0A35, 0x0C52, 0x0A30, 0x0C56, 0x0A2B, 0x0C5A,
347 0x0A26, 0x0C5E, 0x0A21, 0x0C62, 0x0A1C, 0x0C66, 0x0A17, 0x0C6A, 0x0A12, 0x0C6E, 0x0A0E, 0x0C72,
348 0x0A09, 0x0C76, 0x0A04, 0x0C79, 0x09FF, 0x0C7D, 0x09FA, 0x0C81, 0x09F5, 0x0C85, 0x09F0, 0x0C89,
349 0x09EB, 0x0C8D, 0x09E6, 0x0C91, 0x09E1, 0x0C95, 0x09DC, 0x0C99, 0x09D7, 0x0C9D, 0x09D3, 0x0CA0,
350 0x09CE, 0x0CA4, 0x09C9, 0x0CA8, 0x09C4, 0x0CAC, 0x09BF, 0x0CB0, 0x09BA, 0x0CB4, 0x09B5, 0x0CB7,
351 0x09B0, 0x0CBB, 0x09AB, 0x0CBF, 0x09A6, 0x0CC3, 0x09A1, 0x0CC7, 0x099C, 0x0CCA, 0x0997, 0x0CCE,
352 0x0992, 0x0CD2, 0x098D, 0x0CD6, 0x0987, 0x0CD9, 0x0982, 0x0CDD, 0x097D, 0x0CE1, 0x0978, 0x0CE5,
353 0x0973, 0x0CE8, 0x096E, 0x0CEC, 0x0969, 0x0CF0, 0x0964, 0x0CF3, 0x095F, 0x0CF7, 0x095A, 0x0CFB,
354 0x0955, 0x0CFE, 0x0950, 0x0D02, 0x094B, 0x0D06, 0x0945, 0x0D09, 0x0940, 0x0D0D, 0x093B, 0x0D11,
355 0x0936, 0x0D14, 0x0931, 0x0D18, 0x092C, 0x0D1C, 0x0927, 0x0D1F, 0x0921, 0x0D23, 0x091C, 0x0D26,
356 0x0917, 0x0D2A, 0x0912, 0x0D2D, 0x090D, 0x0D31, 0x0908, 0x0D35, 0x0902, 0x0D38, 0x08FD, 0x0D3C,
357 0x08F8, 0x0D3F, 0x08F3, 0x0D43, 0x08EE, 0x0D46, 0x08E8, 0x0D4A, 0x08E3, 0x0D4D, 0x08DE, 0x0D51,
358 0x08D9, 0x0D54, 0x08D3, 0x0D58, 0x08CE, 0x0D5B, 0x08C9, 0x0D5F, 0x08C4, 0x0D62, 0x08BE, 0x0D65,
359 0x08B9, 0x0D69, 0x08B4, 0x0D6C, 0x08AF, 0x0D70, 0x08A9, 0x0D73, 0x08A4, 0x0D77, 0x089F, 0x0D7A,
360 0x0899, 0x0D7D, 0x0894, 0x0D81, 0x088F, 0x0D84, 0x088A, 0x0D87, 0x0884, 0x0D8B, 0x087F, 0x0D8E,
361 0x087A, 0x0D91, 0x0874, 0x0D95, 0x086F, 0x0D98, 0x086A, 0x0D9B, 0x0864, 0x0D9F, 0x085F, 0x0DA2,
362 0x085A, 0x0DA5, 0x0854, 0x0DA9, 0x084F, 0x0DAC, 0x0849, 0x0DAF, 0x0844, 0x0DB2, 0x083F, 0x0DB6,
363 0x0839, 0x0DB9, 0x0834, 0x0DBC, 0x082E, 0x0DBF, 0x0829, 0x0DC2, 0x0824, 0x0DC6, 0x081E, 0x0DC9,
364 0x0819, 0x0DCC, 0x0813, 0x0DCF, 0x080E, 0x0DD2, 0x0809, 0x0DD5, 0x0803, 0x0DD9, 0x07FE, 0x0DDC,
365 0x07F8, 0x0DDF, 0x07F3, 0x0DE2, 0x07ED, 0x0DE5, 0x07E8, 0x0DE8, 0x07E2, 0x0DEB, 0x07DD, 0x0DEE,
366 0x07D7, 0x0DF2, 0x07D2, 0x0DF5, 0x07CD, 0x0DF8, 0x07C7, 0x0DFB, 0x07C2, 0x0DFE, 0x07BC, 0x0E01,
367 0x07B7, 0x0E04, 0x07B1, 0x0E07, 0x07AC, 0x0E0A, 0x07A6, 0x0E0D, 0x07A0, 0x0E10, 0x079B, 0x0E13,
368 0x0795, 0x0E16, 0x0790, 0x0E19, 0x078A, 0x0E1C, 0x0785, 0x0E1F, 0x077F, 0x0E22, 0x077A, 0x0E25,
369 0x0774, 0x0E28, 0x076F, 0x0E2B, 0x0769, 0x0E2D, 0x0763, 0x0E30, 0x075E, 0x0E33, 0x0758, 0x0E36,
370 0x0753, 0x0E39, 0x074D, 0x0E3C, 0x0748, 0x0E3F, 0x0742, 0x0E42, 0x073C, 0x0E44, 0x0737, 0x0E47,
371 0x0731, 0x0E4A, 0x072B, 0x0E4D, 0x0726, 0x0E50, 0x0720, 0x0E53, 0x071B, 0x0E55, 0x0715, 0x0E58,
372 0x070F, 0x0E5B, 0x070A, 0x0E5E, 0x0704, 0x0E60, 0x06FE, 0x0E63, 0x06F9, 0x0E66, 0x06F3, 0x0E69,
373 0x06ED, 0x0E6B, 0x06E8, 0x0E6E, 0x06E2, 0x0E71, 0x06DC, 0x0E74, 0x06D7, 0x0E76, 0x06D1, 0x0E79,
374 0x06CB, 0x0E7C, 0x06C6, 0x0E7E, 0x06C0, 0x0E81, 0x06BA, 0x0E84, 0x06B5, 0x0E86, 0x06AF, 0x0E89,
375 0x06A9, 0x0E8B, 0x06A3, 0x0E8E, 0x069E, 0x0E91, 0x0698, 0x0E93, 0x0692, 0x0E96, 0x068D, 0x0E98,
376 0x0687, 0x0E9B, 0x0681, 0x0E9E, 0x067B, 0x0EA0, 0x0676, 0x0EA3, 0x0670, 0x0EA5, 0x066A, 0x0EA8,
377 0x0664, 0x0EAA, 0x065F, 0x0EAD, 0x0659, 0x0EAF, 0x0653, 0x0EB2, 0x064D, 0x0EB4, 0x0648, 0x0EB7,
378 0x0642, 0x0EB9, 0x063C, 0x0EBC, 0x0636, 0x0EBE, 0x0630, 0x0EC0, 0x062B, 0x0EC3, 0x0625, 0x0EC5,
379 0x061F, 0x0EC8, 0x0619, 0x0ECA, 0x0613, 0x0ECD, 0x060E, 0x0ECF, 0x0608, 0x0ED1, 0x0602, 0x0ED4,
380 0x05FC, 0x0ED6, 0x05F6, 0x0ED8, 0x05F0, 0x0EDB, 0x05EB, 0x0EDD, 0x05E5, 0x0EDF, 0x05DF, 0x0EE2,
381 0x05D9, 0x0EE4, 0x05D3, 0x0EE6, 0x05CD, 0x0EE8, 0x05C7, 0x0EEB, 0x05C2, 0x0EED, 0x05BC, 0x0EEF,
382 0x05B6, 0x0EF2, 0x05B0, 0x0EF4, 0x05AA, 0x0EF6, 0x05A4, 0x0EF8, 0x059E, 0x0EFA, 0x0599, 0x0EFD,
383 0x0593, 0x0EFF, 0x058D, 0x0F01, 0x0587, 0x0F03, 0x0581, 0x0F05, 0x057B, 0x0F08, 0x0575, 0x0F0A,
384 0x056F, 0x0F0C, 0x0569, 0x0F0E, 0x0563, 0x0F10, 0x055D, 0x0F12, 0x0558, 0x0F14, 0x0552, 0x0F16,
385 0x054C, 0x0F18, 0x0546, 0x0F1B, 0x0540, 0x0F1D, 0x053A, 0x0F1F, 0x0534, 0x0F21, 0x052E, 0x0F23,
386 0x0528, 0x0F25, 0x0522, 0x0F27, 0x051C, 0x0F29, 0x0516, 0x0F2B, 0x0510, 0x0F2D, 0x050A, 0x0F2F,
387 0x0504, 0x0F31, 0x04FE, 0x0F33, 0x04F8, 0x0F35, 0x04F2, 0x0F37, 0x04EC, 0x0F39, 0x04E6, 0x0F3B,
388 0x04E0, 0x0F3C, 0x04DB, 0x0F3E, 0x04D5, 0x0F40, 0x04CF, 0x0F42, 0x04C9, 0x0F44, 0x04C3, 0x0F46,
389 0x04BD, 0x0F48, 0x04B7, 0x0F4A, 0x04B1, 0x0F4B, 0x04AB, 0x0F4D, 0x04A5, 0x0F4F, 0x049E, 0x0F51,
390 0x0498, 0x0F53, 0x0492, 0x0F55, 0x048C, 0x0F56, 0x0486, 0x0F58, 0x0480, 0x0F5A, 0x047A, 0x0F5C,
391 0x0474, 0x0F5D, 0x046E, 0x0F5F, 0x0468, 0x0F61, 0x0462, 0x0F63, 0x045C, 0x0F64, 0x0456, 0x0F66,
392 0x0450, 0x0F68, 0x044A, 0x0F69, 0x0444, 0x0F6B, 0x043E, 0x0F6D, 0x0438, 0x0F6E, 0x0432, 0x0F70,
393 0x042C, 0x0F72, 0x0426, 0x0F73, 0x0420, 0x0F75, 0x041A, 0x0F77, 0x0413, 0x0F78, 0x040D, 0x0F7A,
394 0x0407, 0x0F7B, 0x0401, 0x0F7D, 0x03FB, 0x0F7F, 0x03F5, 0x0F80, 0x03EF, 0x0F82, 0x03E9, 0x0F83,
395 0x03E3, 0x0F85, 0x03DD, 0x0F86, 0x03D7, 0x0F88, 0x03D0, 0x0F89, 0x03CA, 0x0F8B, 0x03C4, 0x0F8C,
396 0x03BE, 0x0F8E, 0x03B8, 0x0F8F, 0x03B2, 0x0F91, 0x03AC, 0x0F92, 0x03A6, 0x0F94, 0x03A0, 0x0F95,
397 0x0399, 0x0F96, 0x0393, 0x0F98, 0x038D, 0x0F99, 0x0387, 0x0F9B, 0x0381, 0x0F9C, 0x037B, 0x0F9D,
398 0x0375, 0x0F9F, 0x036F, 0x0FA0, 0x0368, 0x0FA1, 0x0362, 0x0FA3, 0x035C, 0x0FA4, 0x0356, 0x0FA5,
399 0x0350, 0x0FA7, 0x034A, 0x0FA8, 0x0344, 0x0FA9, 0x033D, 0x0FAB, 0x0337, 0x0FAC, 0x0331, 0x0FAD,
400 0x032B, 0x0FAE, 0x0325, 0x0FB0, 0x031F, 0x0FB1, 0x0318, 0x0FB2, 0x0312, 0x0FB3, 0x030C, 0x0FB4,
401 0x0306, 0x0FB6, 0x0300, 0x0FB7, 0x02FA, 0x0FB8, 0x02F3, 0x0FB9, 0x02ED, 0x0FBA, 0x02E7, 0x0FBB,
402 0x02E1, 0x0FBD, 0x02DB, 0x0FBE, 0x02D5, 0x0FBF, 0x02CE, 0x0FC0, 0x02C8, 0x0FC1, 0x02C2, 0x0FC2,
403 0x02BC, 0x0FC3, 0x02B6, 0x0FC4, 0x02AF, 0x0FC5, 0x02A9, 0x0FC6, 0x02A3, 0x0FC7, 0x029D, 0x0FC8,
404 0x0297, 0x0FC9, 0x0290, 0x0FCA, 0x028A, 0x0FCB, 0x0284, 0x0FCC, 0x027E, 0x0FCD, 0x0278, 0x0FCE,
405 0x0271, 0x0FCF, 0x026B, 0x0FD0, 0x0265, 0x0FD1, 0x025F, 0x0FD2, 0x0259, 0x0FD3, 0x0252, 0x0FD4,
406 0x024C, 0x0FD5, 0x0246, 0x0FD6, 0x0240, 0x0FD7, 0x0239, 0x0FD8, 0x0233, 0x0FD9, 0x022D, 0x0FD9,
407 0x0227, 0x0FDA, 0x0221, 0x0FDB, 0x021A, 0x0FDC, 0x0214, 0x0FDD, 0x020E, 0x0FDE, 0x0208, 0x0FDE,
408 0x0201, 0x0FDF, 0x01FB, 0x0FE0, 0x01F5, 0x0FE1, 0x01EF, 0x0FE1, 0x01E8, 0x0FE2, 0x01E2, 0x0FE3,
409 0x01DC, 0x0FE4, 0x01D6, 0x0FE4, 0x01CF, 0x0FE5, 0x01C9, 0x0FE6, 0x01C3, 0x0FE7, 0x01BD, 0x0FE7,
410 0x01B6, 0x0FE8, 0x01B0, 0x0FE9, 0x01AA, 0x0FE9, 0x01A4, 0x0FEA, 0x019D, 0x0FEB, 0x0197, 0x0FEB,
411 0x0191, 0x0FEC, 0x018B, 0x0FEC, 0x0184, 0x0FED, 0x017E, 0x0FEE, 0x0178, 0x0FEE, 0x0172, 0x0FEF,
412 0x016B, 0x0FEF, 0x0165, 0x0FF0, 0x015F, 0x0FF0, 0x0159, 0x0FF1, 0x0152, 0x0FF1, 0x014C, 0x0FF2,
413 0x0146, 0x0FF2, 0x0140, 0x0FF3, 0x0139, 0x0FF3, 0x0133, 0x0FF4, 0x012D, 0x0FF4, 0x0127, 0x0FF5,
414 0x0120, 0x0FF5, 0x011A, 0x0FF6, 0x0114, 0x0FF6, 0x010D, 0x0FF7, 0x0107, 0x0FF7, 0x0101, 0x0FF7,
415 0x00FB, 0x0FF8, 0x00F4, 0x0FF8, 0x00EE, 0x0FF9, 0x00E8, 0x0FF9, 0x00E2, 0x0FF9, 0x00DB, 0x0FFA,
416 0x00D5, 0x0FFA, 0x00CF, 0x0FFA, 0x00C8, 0x0FFB, 0x00C2, 0x0FFB, 0x00BC, 0x0FFB, 0x00B6, 0x0FFB,
417 0x00AF, 0x0FFC, 0x00A9, 0x0FFC, 0x00A3, 0x0FFC, 0x009D, 0x0FFC, 0x0096, 0x0FFD, 0x0090, 0x0FFD,
418 0x008A, 0x0FFD, 0x0083, 0x0FFD, 0x007D, 0x0FFE, 0x0077, 0x0FFE, 0x0071, 0x0FFE, 0x006A, 0x0FFE,
419 0x0064, 0x0FFE, 0x005E, 0x0FFE, 0x0057, 0x0FFF, 0x0051, 0x0FFF, 0x004B, 0x0FFF, 0x0045, 0x0FFF,
420 0x003E, 0x0FFF, 0x0038, 0x0FFF, 0x0032, 0x0FFF, 0x002B, 0x0FFF, 0x0025, 0x0FFF, 0x001F, 0x0FFF,
421 0x0019, 0x0FFF, 0x0012, 0x0FFF, 0x000C, 0x0FFF, 0x0006, 0x0FFF,
422];
423
424lazy_static::lazy_static! {
425 static ref WORD_6A56C8: Vec<i16> = init_table();
426}
427
428fn init_table() -> Vec<i16> {
429 let mut table = Vec::with_capacity(0x10000);
430 let mut cx: i16 = 0;
431 let mut dx: i16 = 0;
432 for _ in 0..0x8000 {
433 table.push(dx);
434 wrapping! {
435 dx -= 1;
436 cx += 1;
437 }
438 table.push(cx);
439 }
440 table
441}
442
443struct PcmDecoder {
444 pcm_data: Vec<u8>,
445 encoded: MemReader,
446 pcm_size: usize,
447 extra: u32,
448 dword_43a214: Vec<i32>,
449 unk_6a16c8: Vec<u8>,
450 a2: Vec<i32>,
452 a3: Vec<i32>,
454}
455
456impl PcmDecoder {
457 pub fn new<R: Read + Seek>(
458 mut input: R,
459 pcm_size: usize,
460 extra: u32,
461 mode: Mode,
462 ) -> Result<Self> {
463 if extra > 4 {
464 return Err(anyhow::anyhow!("Unsupported PCM extra: {}", extra));
465 }
466 let packed_size = input.read_u32()?;
467 let pcm_data = vec![0u8; pcm_size + 8192];
468 let encoded = match mode {
469 Mode::Lzss => {
470 let mut data = vec![0u8; packed_size as usize];
471 input.read_exact(&mut data)?;
472 Self::unpack_v1(&data)?
473 }
474 Mode::Zlib => {
475 let mut decoder = flate2::read::ZlibDecoder::new(input);
476 let mut data = Vec::new();
477 decoder.read_to_end(&mut data)?;
478 data
479 }
480 _ => return Err(anyhow::anyhow!("Unsupported PCM mode: {:?}", mode)),
481 };
482 Ok(Self {
483 pcm_data,
484 encoded: MemReader::new(encoded),
485 pcm_size,
486 extra,
487 dword_43a214: vec![0; 0x10],
488 unk_6a16c8: vec![0; 0x2000],
489 a2: vec![0; 0x1000],
490 a3: vec![0; 0x1000],
491 })
492 }
493
494 pub fn unpack(mut self) -> Result<Vec<u8>> {
495 let mut reader = MemReaderRef::new(&UNK_43A254);
496 reader.pos = self.extra as usize * 0x40;
497 for i in 0..0x10 {
498 self.dword_43a214[i] = reader.read_i32()?;
499 }
500 self.decode_v1()?;
501 self.pcm_data.truncate(self.pcm_size);
502 Ok(self.pcm_data)
503 }
504
505 fn decode_v1(&mut self) -> Result<()> {
506 let v14 = self.pcm_size / 2;
507 let mut v5 = 0;
508 let mut decoded = 0;
509 let mut dst_sizea = 0;
510 while dst_sizea < v14 {
511 self.sub_4121c0(v5)?;
512 v5 += 8192;
513 self.sub_411ab0(12);
514 let mut v6 = decoded;
515 let mut v7 = 0;
516 let mut v8 = 0;
517 let mut v9 = 32;
518 while v9 > -4064 {
519 if v7 + dst_sizea < v14 {
520 let mut v11;
521 if v9 > 0 && dst_sizea != 0 {
522 let v10 = (v7 as i64).wrapping_mul(self.a2[v8] as u32 as i64)
523 + (v9 as i64).wrapping_mul(i16::from_le_bytes([
524 self.pcm_data[v6],
525 self.pcm_data[v6 + 1],
526 ]) as i64);
527 v11 = (((v10 >> 32) & 0x1F) as i32 + v10 as i32) >> 5;
528 } else {
529 v11 = self.a2[v8];
530 }
531 if v11 > 32767 {
532 v11 = 32767;
533 } else if v11 < -32768 {
534 v11 = -32768;
535 }
536 let data = (v11 as i16).to_le_bytes();
537 self.pcm_data[v6] = data[0];
538 self.pcm_data[v6 + 1] = data[1];
539 }
540 v7 += 1;
541 v6 += 2;
542 v8 += 1;
543 v9 -= 1;
544 }
545 decoded += 8128;
546 dst_sizea += 4064;
547 }
548 Ok(())
549 }
550
551 fn sub_4121c0(&mut self, a1: usize) -> Result<()> {
552 let mut v1 = a1;
553 let mut v5 = 1;
554 for _ in 0..0x1000 {
555 self.unk_6a16c8[v5] = self.encoded.cpeek_u8_at(v1 as u64)?;
556 v1 += 1;
557 v5 += 2;
558 }
559 v5 = 0;
560 for _ in 0..0x800 {
561 let v7 = self.encoded.cpeek_u8_at(v1 as u64 + 0x800)?;
562 let v8 = self.encoded.cpeek_u8_at(v1 as u64)?;
563 self.unk_6a16c8[v5] = (v7 >> 4) | (v8 & 0xF0);
564 self.unk_6a16c8[v5 + 2] = (v8 << 4) | (v7 & 0x0F);
565 v5 += 4;
566 v1 += 1;
567 }
568 let mut v9 = 0;
569 v5 = 0;
570 for v11_chunk in (0..32768).step_by(16) {
571 let result = self.dword_43a214[v11_chunk / 0x1000];
572 let i1 = u16::from_le_bytes([self.unk_6a16c8[v5], self.unk_6a16c8[v5 + 1]]) as usize;
573 let i2 =
574 u16::from_le_bytes([self.unk_6a16c8[v5 + 2], self.unk_6a16c8[v5 + 3]]) as usize;
575 self.a2[v9] = result.wrapping_mul(WORD_6A56C8[i1] as i32);
576 self.a3[v9] = result.wrapping_mul(WORD_6A56C8[i2] as i32);
577 v9 += 1;
578 v5 += 4;
579 }
580 for i in v9..4096 {
581 self.a2[i] = 0;
582 self.a3[i] = 0;
583 }
584 Ok(())
585 }
586
587 fn sub_411ab0(&mut self, a1: i32) {
588 let mut v4 = 1 << a1;
589 let mut v5 = 1;
590 let mut v68 = 1;
591 let mut v6 = 1 << a1;
592 let v79 = 1 << a1;
593 if a1 >= 3 {
594 let mut v7 = v4 >> 1;
595 let mut v59 = a1 - 2;
596 loop {
597 let v63 = v4;
598 let v82 = DWORD_43A358[v5 as usize * 2];
599 let v66 = v7;
600 let mut v8 = v7 >> 1;
601 let v62 = v7 >> 1;
602 let v80 = DWORD_43A358[1 + 2 * v5 as usize];
603 let mut v77 = 0;
604 if v6 > 0 {
605 let mut v73 = 0;
606 let mut v69 = v8;
607 let mut v75 = v7;
608 let v9 = v8 + 1;
609 let v10 = v7 + v8;
610 let mut v64 = v9;
611 let mut v11 = 1;
612 let mut v12 = v10 + 1;
613 let mut v71 = v10;
614 let mut v13 = v7 + 1;
615 loop {
616 let v14 = self.a2[v75 as usize];
617 let v15 = self.a2[v73 as usize];
618 let v16 = self.a3[v11 as usize - 1] - self.a3[v13 as usize - 1];
619 self.a2[v73 as usize] += self.a2[v75 as usize];
620 self.a3[v11 as usize - 1] += self.a3[v13 as usize - 1];
621 self.a2[v75 as usize] = v15 - v14;
622 self.a3[v13 as usize - 1] = v16;
623 let v17 = self.a2[v13 as usize];
624 let v18 = self.a2[v11 as usize] - v17;
625 let v19 = self.a3[v11 as usize] - self.a3[v13 as usize];
626 self.a2[v11 as usize] += v17;
627 self.a3[v11 as usize] += self.a3[v13 as usize];
628 self.a2[v13 as usize] = (((v18 as i64).wrapping_mul(v82 as i64) as u64
629 >> 12)
630 + ((v19 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
631 as i32;
632 let pv = (v19 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
633 let nv = (v18 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
634 self.a3[v13 as usize] = pv.wrapping_sub(nv) as i32;
635 let v20 = self.a2[v69 as usize] - self.a2[v71 as usize];
636 let v21 = v64;
637 let v22 = self.a3[v64 as usize - 1] - self.a3[v12 as usize - 1];
638 self.a2[v69 as usize] += self.a2[v71 as usize];
639 self.a3[v21 as usize - 1] += self.a3[v12 as usize - 1];
640 self.a2[v71 as usize] = v22;
641 self.a3[v12 as usize - 1] = -v20;
642 let v23 = self.a2[v12 as usize];
643 let v24 = self.a2[v64 as usize] - v23;
644 let v25 = self.a3[v64 as usize] - self.a3[v12 as usize];
645 self.a2[v21 as usize] += v23;
646 self.a3[v21 as usize] += self.a3[v12 as usize];
647 let pv = (v25 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
648 let nv = (v24 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
649 self.a2[v12 as usize] = pv.wrapping_sub(nv) as i32;
650 self.a3[v12 as usize] = (-((((v24 as i64).wrapping_mul(v82 as i64) as u64
651 >> 12)
652 + ((v25 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
653 as i64)) as i32;
654 v13 += v63;
655 v75 += v63;
656 v11 += v63;
657 v73 += v63;
658 v12 += v63;
659 v71 += v63;
660 v77 += v63;
661 v69 += v63;
662 v64 += v63;
663 if v77 >= v79 {
664 break;
665 }
666 }
667 v8 = v62;
668 v5 = v68;
669 v7 = v66;
670 v6 = 1 << a1;
671 }
672 if v8 > 2 {
673 let mut v70 = 2;
674 let mut v72 = v7 + 2;
675 let mut v74 = v8 + 2;
676 let mut v27 = 1 + 4 * v5;
677 let mut v60 = v8 - 2;
678 let mut v76 = v8 + 2 + v7;
679 loop {
680 let v83 = DWORD_43A358[v27 as usize - 1];
681 let v81 = DWORD_43A358[v27 as usize];
682 let mut v78 = 0;
683 if v6 > 0 {
684 let mut v28 = v70;
685 let mut v29 = v72;
686 let mut v65 = v74;
687 let mut v85 = v76;
688 loop {
689 let v31 = self.a2[v29 as usize];
690 let v32 = self.a2[v28 as usize] - v31;
691 let v33 = self.a3[v28 as usize] - self.a3[v29 as usize];
692 self.a2[v28 as usize] += v31;
693 self.a3[v28 as usize] += self.a3[v29 as usize];
694 self.a2[v29 as usize] =
695 (((v32 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
696 + ((v33 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
697 as i32;
698 let pv = (v33 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
699 let nv = (v32 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
700 self.a3[v29 as usize] = pv.wrapping_sub(nv) as i32;
701 let v34 = self.a2[v65 as usize] - self.a2[v85 as usize];
702 let v35 = self.a3[v65 as usize] - self.a3[v85 as usize];
703 self.a2[v65 as usize] += self.a2[v85 as usize];
704 self.a3[v65 as usize] += self.a3[v85 as usize];
705 let pv = (v35 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
706 let nv = (v34 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
707 self.a2[v85 as usize] = pv.wrapping_sub(nv) as i32;
708 self.a3[v85 as usize] =
709 (-((((v34 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
710 + ((v35 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
711 as i64)) as i32;
712 v29 += v63;
713 v85 += v63;
714 v28 += v63;
715 v65 += v63;
716 v78 += v63;
717 if v78 >= v79 {
718 break;
719 }
720 }
721 v5 = v68;
722 v6 = 1 << a1;
723 }
724 v27 += 2 * v5;
725 v70 += 1;
726 v72 += 1;
727 v74 += 1;
728 v76 += 1;
729 v60 -= 1;
730 if v60 == 0 {
731 break;
732 }
733 }
734 }
735 v68 = 2 * v5;
736 v59 -= 1;
737 if v59 == 0 {
738 break;
739 }
740 v7 = v62;
741 v5 *= 2;
742 v4 = v66;
743 }
744 }
745 if !(a1 < 2 || v6 <= 0) {
746 let mut v37 = 1;
747 let mut v38 = 3;
748 let mut v88 = (v6 as u32 + 3) >> 2;
749 loop {
750 let v39 = self.a2[v37 as usize - 1];
751 let v40 = self.a2[v37 as usize + 1];
752 let v41 = self.a3[v38 as usize - 3] - self.a3[v38 as usize - 1];
753 self.a2[v37 as usize - 1] = v40 + v39;
754 v37 += 4;
755 self.a3[v38 as usize - 3] += self.a3[v38 as usize - 1];
756 self.a2[v37 as usize - 3] = v39 - v40;
757 self.a3[v38 as usize - 1] = v41;
758 let v42 = self.a2[v38 as usize];
759 let v43 = self.a3[v38 as usize - 2] - self.a3[v38 as usize];
760 v38 += 4;
761 let v44 = self.a2[v37 as usize - 4] - v42;
762 self.a2[v37 as usize - 4] += v42;
763 self.a3[v38 as usize - 6] += self.a3[v38 as usize - 4];
764 self.a2[v38 as usize - 4] = v43;
765 self.a3[v38 as usize - 4] = -v44;
766 v88 -= 1;
767 if v88 == 0 {
768 break;
769 }
770 }
771 v6 = v79;
772 }
773 let mut v45 = 0;
774 if v6 > 0 {
775 let mut v47 = 1;
776 let mut v89 = (v79 as u32 + 1) >> 1;
777 loop {
778 let v48 = self.a2[v47 as usize];
779 let v49 = self.a3[v47 as usize - 1] - self.a3[v47 as usize];
780 let v50 = self.a2[v45 as usize] - v48;
781 v47 += 2;
782 self.a2[v45 as usize] += v48;
783 v45 += 2;
784 self.a3[v47 as usize - 3] += self.a3[v47 as usize - 2];
785 self.a2[v47 as usize - 2] = v50;
786 self.a3[v47 as usize - 2] = v49;
787 v89 -= 1;
788 if v89 == 0 {
789 break;
790 }
791 }
792 v45 = 0;
793 v6 = v79;
794 }
795 let mut v51 = 0;
796 let mut result = v6 / 2;
797 let v67 = v6 / 2;
798 let mut v90 = 1;
799 if v6 - 1 > 1 {
800 let mut v54 = 1;
801 loop {
802 while result <= v51 {
803 v51 -= result;
804 result /= 2;
805 }
806 v51 += result;
807 if v90 < v51 {
808 self.a2.swap((v45 + v51) as usize, v54 as usize);
809 self.a3.swap(v51 as usize, v54 as usize);
810 }
811 v54 += 1;
812 v90 += 1;
813 if v90 >= v79 - 1 {
814 break;
815 }
816 result = v67;
817 }
818 v6 = v79;
819 }
820 while v6 > 0 {
821 let eax = self.a2[v45] << 4;
822 let edx = if eax < 0 { 0x3FFF } else { 0 };
823 self.a2[v45] = eax.wrapping_add(edx) >> 14;
824 v45 += 1;
825 v6 -= 1;
826 }
827 }
828
829 fn unpack_v1(input: &[u8]) -> Result<Vec<u8>> {
830 let packed_size = input.len();
831 let mut flag = 0;
832 let mut src = 0;
833 let mut output = Vec::new();
834 while src < packed_size {
835 flag >>= 1;
836 if (flag & 0x100) == 0 {
837 flag = input[src] as u32 | 0xFF00;
838 src += 1;
839 }
840 if (flag & 1) != 0 {
841 output.push(input[src]);
842 src += 1;
843 } else {
844 if src >= packed_size {
845 break;
846 }
847 let mut offset;
848 let count;
849 let ctl = input[src] as u32;
850 src += 1;
851 if ctl >= 0xc0 {
852 offset = input[src] as usize | (((ctl & 3) << 8) as usize);
853 src += 1;
854 count = 4 + ((ctl >> 2) & 0xF) as usize;
855 } else if ctl & 0x80 != 0 {
856 offset = (ctl & 0x1F) as usize;
857 count = (2 + ((ctl >> 5) & 3)) as usize;
858 if offset == 0 {
859 offset = input[src] as usize;
860 src += 1;
861 }
862 } else if ctl == 0x7F {
863 count = (2 + u16::from_le_bytes([input[src], input[src + 1]])) as usize;
864 offset = u16::from_le_bytes([input[src + 2], input[src + 3]]) as usize;
865 src += 4;
866 } else {
867 offset = u16::from_le_bytes([input[src], input[src + 1]]) as usize;
868 src += 2;
869 count = (ctl + 4) as usize;
870 }
871 let dst = output.len();
872 let copy_src = dst - offset;
873 for i in 0..count {
874 output.push(output[copy_src + i]);
875 }
876 }
877 }
878 Ok(output)
879 }
880}